namespace SimpleWebServices.Web.UI.Html.Validation
{
    using System;
    using System.Configuration;
    using System.Diagnostics.CodeAnalysis;
    using System.Xml.Serialization;
    using SimpleWebServices.Data;
    using SimpleWebServices.Web.UI.Html.Elements;

    [XmlRoot("validator")]
    public sealed class ValidatorSettings
    {
        public ValidatorSettings()
        {
            this.Data = new DataCollection();
        }

        [XmlElement("data")]
        public DataCollection Data
        {
            get;
            set;
        }

        [XmlAttribute("display")]
        public string Display
        {
            get;
            set;
        }

        [XmlAttribute("for")]
        public string For
        {
            get;
            set;
        }

        [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "The naming is intentionally the same as HTML.")]
        [XmlAttribute("type")]
        public string Type
        {
            get;
            set;
        }

        public void AddValidator(IElement element)
        {
            this.AddValidator(element as IInnerElements);
        }

        private void AddValidator(IInnerElements element)
        {
            if (null == element)
            {
                throw new ArgumentNullException("element");
            }

            Type type = System.Type.GetType(this.Type);

            IValidate validator = Activator.CreateInstance(type) as IValidate;
            if (null == validator)
            {
                throw new ConfigurationErrorsException(this.Type + " does not implement IValidate.");
            }

            IInnerElements display = element[this.Display] as IInnerElements;
            if (null == display)
            {
                throw new ConfigurationErrorsException(this.Display + " does not implement IInnerElements.");
            }
            else
            {
                validator.Display = display;
            }

            validator.Configure(element, this.Data);

            IValidation control = null;
            if (this.For == element.Id)
            {
                control = element as IValidation;
            }
            else
            {
                control = element[this.For] as IValidation;
            }

            if (null == control)
            {
                throw new ConfigurationErrorsException(this.For + " does not implement IValidation.");
            }
            else
            {
                control.Validator = validator;
            }
        }
    }
}